/**
 * Created by forest on 10/27/14.
 */

if (!zx_ns_table) {
    var zx_ns_table = (function () {

        var DT_PARAMETERS_MAP = new Object();

        function removeTableBody(tableId, remove) {
            if (remove) {
                $("#{0} tbody tr".format(tableId)).remove();
            } else {
                $("#{0} tbody tr".format(tableId)).css("visibility", "hidden");
            }
        }

        function buildPagination(tableId, data, callback) {
            // 处理callback
            var callbackName = null;
            if (callback && callback.name) { // 不是匿名函数
                callbackName = callback.name;
            } else {
                callbackName = callback;
            }
            if (data) {
                if (data.hasOwnProperty("max")) {
                    delete data["max"];
                }
                if (data.hasOwnProperty("offset")) {
                    delete data["offset"];
                }
            }

            // ajax url
            var href = "javascript:zx_ns_table.loadAjaxHtmlData('{0}', '{1}', {2}, " + JSON.stringify(data) + ", true);";

            var $container = $("#{0} .pagination-container".format(tableId));
            if ($container.find(".step").length > 0) {
                var currentStep = parseInt($container.find(".currentStep").html());
                $container.find(".step.gap").remove();
                var $children = $container.find("a:not(.prevLink):not(.nextLink),span");
                var $prev = $container.find(".prevLink");
                var $next = $container.find(".nextLink");
                if ($prev.length == 0) {
                    $prev = $("<a class='prevLink disabled'>‹</a>");
                    $container.prepend($prev);
                }
                if ($next.length == 0) {
                    $next = $("<a class='nextLink disabled'>›</a>");
                    $container.append($next);
                }
                for (var i = 0; i < $children.length; i++) {
                    var $item = $($children.get(i));
                    if ($item.hasClass("step")) {
                        $item.addClass("paginate_button").attr("aria-controls", "DataTables_Table_3").attr("tabindex", 0).attr("data-dt-idx", i + 1).removeClass("step");
                    } else { // current step
                        var $current = $("<a></a>");
                        $current.addClass("paginate_button").addClass("current").attr("aria-controls", "DataTables_Table_3").attr("data-dt-idx", i + 1).attr("tabindex", 0).html(currentStep);
                        $item.after($current);
                        $item.remove();
                    }
                }
                $prev.addClass("paginate_button").addClass("previous").attr("aria-controls", "DataTables_Table_3").attr("tabindex", 0).attr("data-dt-idx", 0).removeClass(".prevLink");
                $next.addClass("paginate_button").addClass("next").attr("aria-controls", "DataTables_Table_3").attr("tabindex", 0).attr("data-dt-idx", $children.length).removeClass("nextLink");

                // update href
                var $as = $container.find("a.paginate_button:not(.current):not(.disabled)");
                for (var i = 0; i < $as.length; i++) {
                    var $item = $($as.get(i));
                    $item.attr("href", href.format(tableId, $item.attr("href")), callbackName);
                }
                $container.removeClass("hide");
                return $container.closest(".datatable-footer");
            } else {
                return null;
            }
        }

        function showLoading(tableId, autoHide) {
            var block = $("#{0}".format(tableId)).closest(".datatable-scroll").parent();
            $(block).block({
                message: '<i class="icon-spinner4 spinner"></i>',
                overlayCSS: {
                    backgroundColor: '#fff',
                    opacity: 0.8,
                    cursor: 'wait'
                },
                css: {
                    width: 16,
                    border: 0,
                    padding: 0,
                    backgroundColor: 'transparent'
                }
            });
            if (autoHide) {
                setTimeout(function () {
                    $(block).unblock();
                }, 2000);
            }
        }

        function hideLoading(tableId) {
            var block = $("#{0}".format(tableId)).closest(".datatable-scroll").parent();
            $(block).unblock();
        }


        function cacheParameters(tableId, url, callback, data, noDataText) {
            var params = new Object();
            params["url"] = url;
            params["callback"] = callback;
            params["data"] = data;
            params["noDataText"] = noDataText;
            DT_PARAMETERS_MAP[tableId] = params;
        }


        // add data from params to url
        // function addData2Url(tableId, url) {
        //     var data = DT_PARAMETERS_MAP[tableId]["data"];
        //     if (data) {
        //         if (url.indexOf('?') >= 0) {
        //             url = url + "&";
        //         } else {
        //             url = url + "?";
        //         }
        //         for (var key in data) {
        //             if (key !== undefined) {
        //                 if (!zx_ns_common.getUrlVar(key, url)) {
        //                     url += (key + "=" + encodeURIComponent(data[key]) + "&" );
        //                 }
        //             }
        //         }
        //     }
        //     return url;
        // }

        var loadAjaxHtmlData = function (tableId, url, callback, data, skipFilters, noDataText) {
            if (noDataText == undefined) {
                noDataText = '暂无数据';
            }
            cacheParameters(tableId, url, callback, data, noDataText);
            url = initSortingUrl(tableId, url);
            if (!skipFilters) {
                url = initFilterParameters(tableId, url);
            }
            // url = addData2Url(tableId, url);
            $.ajax({
                url: url,
                dataType: 'html',
                type: 'POST',
                data: data,
                beforeSend: function () {
                    var $tr = $("<tr><td>&nbsp;</td></tr>");
                    $("#{0} tbody".format(tableId)).append($tr);
                    showLoading(tableId);
                },
                success: function (rsp) {
                    removeTableBody(tableId, true);
                    var $container = $("<div></div>");
                    $container.append(rsp);
                    // initTableStyle(tableId, $container);
                    // deal with toggle column
                    // initTableColumns(tableId, $container);
                    // deal with tree view
                    // initTableTree(tableId, $container);
                    $("#{0} tbody".format(tableId)).append($container.html());
                    var pagination = buildPagination(tableId, data, callback);
                    $("#{0}".format(tableId)).next(".pagination-container").html("");
                    $("#{0}".format(tableId)).closest(".datatable-scroll").next(".datatable-footer").remove();
                    if (pagination) {
                        $("#{0}".format(tableId)).closest(".datatable-scroll").next(".datatable-footer").remove();
                        $("#{0}".format(tableId)).closest(".datatable-scroll").after(pagination);
                    }
                    if ($("#{0} tbody".format(tableId)).find("tr:not(.hide)").length == 0) {
                        $("#{0} tbody".format(tableId)).html("<tr class='no-data'><td colspan='100' class='text-center text-muted'>{0}</td></tr>".format(noDataText));
                    }
                    if (callback && typeof callback === "function") {
                        callback(tableId);
                    }
                    hideLoading(tableId);
                },
                error: function () {
                    removeTableBody(tableId, true);
                    hideLoading(tableId);
                }
            });
        };


        function initTableStyle(tableId, $container) {
            $container.find("tr").each(function () {
                $(this).children("td:first").addClass("dark-col");
            });
        }

        function initFilterParameters(tableId, url) {
            if ($("#{0}".format(tableId)).parent().find(".table-filter-container").length > 0) {
                var pureUrl = url;
                if (pureUrl.indexOf('?') != -1) {
                    pureUrl = pureUrl.slice(0, pureUrl.indexOf('?'));
                }
                var vars = zx_ns_common.getUrlVars(url);
                $("#{0}".format(tableId)).parent().find(".table-filter-container").find("[data-table-filter-name]").each(function () {
                    var $this = $(this);
                    var key = zx_ns_common.attrZXValue($this, "data-table-filter-name", "");
//                    console.log(this.tagName);
                    switch (this.tagName) {
                        case 'SELECT':
                        case 'INPUT':
                            vars[key] = $(this).val();
                            break;
                        default:
                            vars[key] = $(this).text();
                            break;
                    }
                });
                var params = '';
                $.each(vars, function (key, value) {
                    params += key + "=" + value + "&";
                });
                pureUrl = "{0}?{1}".format(pureUrl, params);
                return pureUrl;
            } else {
                return url;
            }
        }

        function initTableTree(tableId, $container) {
            var $table = $("#{0}".format(tableId));
            if (!$table[0].hasAttribute("data-tree")) {
                return;
            }
            if ($table.find("tr th.tree-oper").size() == 0) {
                $table.find("tr").prepend("<th class='tree-oper'></th>");
            }
            $container.find("tr").prepend("<td class='tree-oper'></td>");
            $container.find("tr[data-parent-row] td.tree-oper").append("<a class='tree-icon' onclick='zx_ns_table.toggleTreeIcon(this);' href='javascript:;'><i class='fa fa-plus-square'></i></a>");
            $container.find("tr:not(tr[data-parent-row]:not(.hide))").css("display", "none");
        }

        var toggleTreeIcon = function (sender) {
            var $this = $(sender);
            var key = $this.closest("tr").attr("data-key");
            if ($this.find("i").hasClass("fa-plus-square")) {
                $this.find("i").addClass("fa-minus-square").removeClass("fa-plus-square");
                $this.closest("tr").siblings("tr[data-key={0}]".format(key)).show('slow');
            } else {
                $this.find("i").removeClass("fa-minus-square").addClass("fa-plus-square");
                $this.closest("tr").siblings("tr[data-key={0}]".format(key)).hide('slow');
            }
        };

        function initTableColumns(tableId, $tbodyContainer) {
            var $triggerId = zx_ns_common.attrZXValue($("#{0}".format(tableId)), "data-toggle-trigger", "");
            var $trigger = null;
            if ($trigger != "") {
                $trigger = $($triggerId);
                $("#{0} tr".format(tableId)).each(function () {
                    setTableRow($(this), $trigger);
                });
                $tbodyContainer.find("tr:not(.hide)").each(function () {
                    setTableRow($(this), $trigger);
                });
            }
        }

        var setTableColumns = function ($table, $trigger) {
            $table.find("tr").each(function () {
                setTableRow($(this), $trigger);
            });
        };

        function setTableRow($row, $trigger) {
            $trigger.find("[type=checkbox]:checked").each(function () {
                var iCol = parseInt(zx_ns_common.attrZXValue($(this), "data-trigger-column-index", -1));
                $row.find("[{0}]:eq({1})".format("data-trigger-column", iCol)).removeClass("hide");
            });
            $trigger.find("[type=checkbox]:not(:checked)").each(function () {
                var iCol = parseInt(zx_ns_common.attrZXValue($(this), "data-trigger-column-index", -1));
                $row.find("[{0}]:eq({1})".format("data-trigger-column", iCol)).addClass("hide");
            });
        }

        var toggleTableColumns = function ($table, $trigger) {
            $trigger.find("[type=checkbox][data-trigger-column-index]").click(function () {
                setTableColumns($table, $trigger);
            });
        };

        var initTableSorting = function ($table) {
            var $sortCol = $table.find("th.sorting_asc");
            $sortCol = $table.find("th.sorting_desc");
            $table.find("th.sort").each(function (index, item) {
                if ($sortCol.length == 0) {
                    if (index == 0) {
                        $(item).addClass("sorting_asc").attr("sorting_col", true);
                    } else {
                        $(item).addClass("sorting").attr("sorting_col", false);
                    }
                } else {
                    if ($sortCol.attr("data-sort-field") == $(item).attr("data-sort-field")) {
                        $(item).attr("sorting_col", true);
                    } else {
                        $(item).addClass("sorting").attr("sorting_col", false);
                    }
                }
            }).click(function () {
                var $this = $(this);
                if ($this.hasClass("sorting") || $this.hasClass("sorting_desc")) {
                    $this.closest("thead").find("[sorting_col=true]").attr("sorting_col", false);
                    $this.closest("thead").find("th.sorting_asc").removeClass("sorting_asc").addClass("sorting");
                    $this.closest("thead").find("th.sorting_desc").removeClass("sorting_desc").addClass("sorting");
                    $this.addClass("sorting_asc").removeClass("sorting").attr("sorting_col", true);
                } else {
                    $this.closest("thead").find("[sorting_col=true]").attr("sorting_col", false);
                    $this.closest("thead").find("th.sorting_asc").removeClass("sorting_asc").addClass("sorting");
                    $this.closest("thead").find("th.sorting_desc").removeClass("sorting_desc").addClass("sorting");
                    $this.addClass("sorting_desc").removeClass("sorting").attr("sorting_col", true);
                }
                var params = DT_PARAMETERS_MAP[$table.attr("id")];
                loadAjaxHtmlData($table.attr("id"), params.url, params.callback, params.data, params.noDataText);
            });
        };

        function initSortingUrl(tableId, url) {
            var $header = $("#{0} th[sorting_col=true]".format(tableId));
            if ($header.length > 0) {
                return buildSortingUrl(url, $header.attr("data-sort-field"), $header.hasClass("sorting_asc") ? 'asc' : 'desc');
            } else {
                return url;
            }
        }

        function buildSortingUrl(url, sortField, sortOrder) {
            var pureUrl = url;
            if (pureUrl.indexOf('?') != -1) {
                pureUrl = pureUrl.slice(0, pureUrl.indexOf('?'));
            }
            var vars = zx_ns_common.getUrlVars(url);
            vars["sort"] = sortField;
            vars["order"] = sortOrder;
            var params = '';
            $.each(vars, function (key, value) {
                params += key + "=" + value + "&";
            });
            pureUrl = "{0}?{1}".format(pureUrl, params);
            return pureUrl;
        }

        return {
            loadAjaxHtmlData: loadAjaxHtmlData,
            toggleTableColumns: toggleTableColumns,
            setTableColumns: setTableColumns,
            initTableSorting: initTableSorting,
            toggleTreeIcon: toggleTreeIcon
        };
    })();
}